package com.gmrz.uaf.servlet.v1.handler;

import com.gmrz.uaf.common.Constants;
import com.gmrz.uaf.common.GuiceUtil;
import com.gmrz.uaf.protocol.v1.json.UAFSchemaBuilder;
import com.gmrz.uaf.protocol.v1.schema.OOBInfo;
import com.gmrz.uaf.remote.protocol.v1.processor.UAPOOBStatusProcessor;
import com.gmrz.uaf.server.ServerContext;
import com.gmrz.uaf.servlet.v1.request.OOBStatusContext;
import com.gmrz.uaf.servlet.v1.request.ReceiveReqPayload;
import com.gmrz.uaf.servlet.v1.response.FidoRespPayload;
import com.gmrz.uaf.servlet.v1.validation.PayloadValidationException;
import com.gmrz.uaf.servlet.v1.validation.RestValidator;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.lang.reflect.Type;

public class UAPOOBStatusRequestHandler extends UAFBaseHandler {
    private static final Logger LOG = LogManager.getLogger(UAPOOBStatusRequestHandler.class);

    /**
     * {
     * "context":{
     * "authToken":"0r2orLw8t_0cAjm5mGbGaomdVvUCfjjzhVUd9wdqBpA"
     * }
     * }
     *
     * @param request
     * @return {
     * {"statusCode":1200,"description":"OK","uafRequest":{"scanData":"test","status":0}}
     */
    public String oobStatus(String request) {
        LOG.info("[/oob/status][begin]");
        ServerContext.getServerContext().getFidoLog().setRequest(request);
        Gson gson = UAFSchemaBuilder.getGson();
        FidoRespPayload<OOBInfo> respPayload = new FidoRespPayload<OOBInfo>();
        Type reqType = new TypeToken<ReceiveReqPayload<OOBStatusContext>>() {
        }.getType();
        String response = null;
        try {
            ReceiveReqPayload<OOBStatusContext> reqPayload = gson.fromJson(request, reqType);
//            logRequest(request, reqPayload.getContext().getTransNo(), reqPayload.getContext().getUserName(),
//                    reqPayload.getContext().getAppID(), null, null, Constants.Method.OOB_STATUS);
            validate(reqPayload);
            UAPOOBStatusProcessor processor = GuiceUtil.getProcessorInjector()
                    .getInstance(UAPOOBStatusProcessor.class);
            OOBStatusContext context = reqPayload.getContext();
            OOBInfo requests = processor.oobStatus(context.getAuthToken());
            String requestsJson = gson.toJson(requests);
            LOG.info("response=" + requestsJson);
            respPayload.setStatusCode(Constants.StatusCode.OK.getCode());
            respPayload.setDescription("OK");
            respPayload.setUafRequest(requests);
            response = gson.toJson(respPayload);
        } catch (Exception ex) {
            LOG.error("oobStatus error",ex);
            response = buildFidoRespFromException(respPayload, ex);
        }
        LOG.info("[/oob/status][end]");
        return response;
    }

    void validate(ReceiveReqPayload<OOBStatusContext> reqPayload) throws PayloadValidationException {
        if ((null == reqPayload) || (null == reqPayload.getContext())) {
            throw new PayloadValidationException("context", RestValidator.VALIDATION_ERROR.EMPTY);
        }
        OOBStatusContext context = reqPayload.getContext();
        RestValidator.validate("authToken", context.getAuthToken());
    }
}
